home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / comm / bbs / cit_src_7H21.lha / vortex.c < prev    next >
C/C++ Source or Header  |  1997-08-22  |  8KB  |  307 lines

  1. /**
  2.                                vortex.c
  3.  
  4.  Network "vortex" (aka infinite loop) handling code.
  5.  
  6.  
  7. **/
  8. #include "ctdl.h"
  9. #include "math.h"
  10. #include "vortex.h"
  11. #include <dos.h>
  12. /**
  13.                                contents
  14.        InitVortexing()         allocate & initialize buffers
  15.        NotVortex()             checks for vortex possibility
  16. **/
  17.  
  18.  
  19. /**
  20.    External variable definitions
  21. **/
  22. extern CONFIG    cfg;   /* Lots an lots of variables    */
  23. extern MessageBuffer   msgBuf;
  24. extern FILE      *netLog;
  25. extern char *READ_ANY, *APPEND_ANY;
  26. extern char *R_W_ANY, *WRITE_ANY;
  27. extern char logNetResults;
  28. extern char netDebug;
  29.  
  30. /**
  31.  -Vortex Handling-
  32.  
  33.     Vortex: the phenomenon of messages showing up on other systems more than
  34.  once.  The cause is messages being sent from one system to another and
  35.  eventually getting back to the originating system.  This could be in two
  36.  flavors:
  37.  
  38.     A -- B -- C -- eventually back to A
  39.  
  40.     or
  41.  
  42.     A -- B -- C -- D -- eventually back to B or C...
  43.  
  44.     See vortex.h for a complete description of the data records.
  45. **/
  46. char VortexHandle = TRUE;   /* default to Vortex Handling */
  47. SYS_FILE vareaname;         /* set to #netarea plus vortex */
  48. SYS_FILE vfilename;         /* full filename of current vortex file */
  49. static struct elist *head;  /* error list */
  50. void Fix_Name(char *out, char *in, int flag);
  51. static ROOM_ENTRY_TYPE *Vortex_Find_Node( label room );
  52. static int              Check_Sum(char *text);
  53.  
  54. void Fix_Name(char *out, char *in, int flag )
  55.   {
  56.   /**
  57.     take the input name and remove all spaces and special characters
  58.     can be used to append one "normalized" string onto another.
  59.     flag == 1 says to supress all special characters, 0 says replace
  60.     them with "x".
  61.   **/
  62.   int i,j;
  63.   char c;
  64.   j = 0;
  65.   for(i=0; i<strlen(in); i++)
  66.     {
  67.     c = in[i];
  68.     if( isspace(c) ) continue;  /* always supress spaces, tabs, ect. */
  69.     if( flag == 1 && !isalnum(c) ) continue;
  70.     if( !isalnum(c) ) c = 'x';
  71.     out[j++] = c;
  72.     };
  73.   out[j] = '\0';
  74.   }
  75.  
  76. static ROOM_ENTRY_TYPE *Vortex_Find_Node(label room )
  77.   {
  78.   FILE *vfd;
  79.   ROOM_ENTRY_TYPE *vptr;
  80.   int  j;
  81.   strcpy(vfilename,vareaname);
  82.   j = strlen(vfilename);
  83.   vfilename[j++] = '/';
  84.   Fix_Name(&vfilename[j], room, 0);
  85.   vptr = (ROOM_ENTRY_TYPE *)malloc(sizeof(ROOM_ENTRY_TYPE));
  86.   if( vptr == NULL ) return NULL;
  87.   if( (vfd = fopen(vfilename, READ_ANY) ) == NULL )
  88.     {
  89.     /**
  90.       assume it does not exist... create it.
  91.     **/
  92.     memset(vptr, '\0', sizeof(ROOM_ENTRY_TYPE));  /* initialize it */
  93.     }
  94.   else
  95.     {
  96.     /**
  97.       read the entries
  98.     **/
  99.     if( fread(vptr, sizeof(ROOM_ENTRY_TYPE), 1, vfd) != 1 )
  100.       {
  101.       splitF(netLog, "System error with reading %s\n",vfilename);
  102.       free(vptr);
  103.       vptr = NULL;
  104.       };
  105.     fclose(vfd);
  106.     };
  107.   return vptr;
  108.   }
  109.  
  110. /**
  111.  VortexInit()
  112.  
  113.  This function initializes vortexing.  Currently, that means making sure
  114.  that the directory in the #NETAREA called "vortex" exists, it will be created
  115.  if not.  Otherwise, nothing is done at this point.
  116. **/
  117.  
  118. void VortexInit()
  119.   {
  120.   /**
  121.      Initialize the system for vortex checking
  122.      1) create vortex directory if none exits
  123.   **/
  124.   if (!VortexHandle) return ;   /* exit if not doing vortex checking */
  125.   makeSysName(vareaname, "vortex", &cfg.netArea);
  126.   if( access(vareaname, F_OK) != 0 )
  127.     {
  128.     /**
  129.       does not exist, we must create the directory
  130.     **/
  131.     if (mkdir(vareaname) != 0)
  132.       mPrintf("Error creating %s!\n ",vareaname);
  133.     };
  134.   return;
  135.   }
  136.  
  137. /**
  138.  InitVortexing()
  139.  
  140.  This is an initialization function which should be called before each
  141.  session of checking messages in from a network session.
  142.  
  143.  Initialize the error list.
  144. **/
  145. void InitVortexing()
  146.   {
  147.   head = NULL;    /* should already be empty */
  148.   return;         /* nothing else to do */
  149.   }
  150.  
  151. /**
  152.  NotVortex()
  153.  
  154.  This checks to see if the msg in msgBuf is vortexing or not.  FALSE is
  155.  returned if the message should be discarded.  TRUE is not a vortex.
  156.  
  157.  All vortex files are created and updated during this call.
  158.  
  159. **/
  160.  
  161. char NotVortex()
  162.   {
  163.   int i;
  164.   char vortex_flag = TRUE;
  165.   ROOM_ENTRY_TYPE *node;  /* the current node */
  166.   char mynode[20], yournode[20];
  167.   int msgcheck;
  168.  
  169.   /**
  170.     First, we must find the Node Entry that matches the Message
  171.     The function Vortex_Find_Node() will always return a ROOM_ENTRY
  172.     pointer, it will create it if it does not exits.
  173.   **/
  174.   if (!VortexHandle) return TRUE;   /* exit if not doing vortex checking */
  175.   Fix_Name(  mynode, &cfg.codeBuf[cfg.nodeName], 1);
  176.   Fix_Name(yournode, msgBuf.mboname, 1);
  177.   if( strcmp(mynode, yournode) == 0 )
  178.     {
  179.     splitF(netLog, " NotVortex: detected messages from %s\n",msgBuf.mboname);
  180.     splitF(netLog, "            Routed from %s\n",msgBuf.mborig);
  181.     return FALSE;
  182.     };
  183.   if( ( node = Vortex_Find_Node(msgBuf.mbroom) ) == NULL )
  184.     {
  185.     splitF(netLog, " NotVortex: node (%s) bad or no memory\n",msgBuf.mboname);
  186.     return TRUE;
  187.     };
  188.   msgcheck = Check_Sum(msgBuf.mbtext);
  189.   if( node->index == 0 )
  190.     {
  191.     if( logNetResults)
  192.       {
  193.       splitF(netLog, "Msg for unmonitored room %s, adding it.\n", msgBuf.mbroom);
  194.       };
  195.     }
  196.   else  /* check to see if already in list */
  197.     {
  198.     for( i=0; i < node->index && vortex_flag; i++)
  199.       {
  200.       struct elist *error;
  201.       MESSAGE_ENTRY_TYPE *mptr = &node->msg_entry[i];
  202.       if( strcmp(mptr->mbsrcId, msgBuf.mbsrcId) != 0 ) continue;
  203.       if( msgcheck != mptr->check_sum )
  204.         {
  205.         if( strcmp(mptr->mborig,  msgBuf.mborig ) != 0 ) continue;
  206.         if( strcmp(mptr->mbdate,  msgBuf.mbdate ) != 0 ) continue;
  207.         if( strcmp(mptr->mbtime,  msgBuf.mbtime ) != 0 ) continue;
  208.         }
  209.       else
  210.         {
  211.         splitF(netLog, "Vortex Detection: Node: %s SrcId: %s Date: %s Time: %s CHECKSUM: %ld\n"
  212.         , mptr->mborig, mptr->mbsrcId, mptr->mbdate, mptr->mbtime, mptr->check_sum);
  213.         splitF(netLog, "   Message Entry: Node: %s SrcId: %s Date: %s Time: %s CHECKSUM: %ld\n"
  214.         , msgBuf.mborig, msgBuf.mbsrcId, msgBuf.mbdate, msgBuf.mbtime, msgcheck );
  215.  
  216.         };
  217.       vortex_flag = FALSE;
  218.       error = head;
  219.       while( error )
  220.         {
  221.         if( strcmp(error->room,  msgBuf.mbroom)   == 0 &&
  222.             strcmp(error->nodeid, msgBuf.mborig)  == 0 ) break;
  223.         error = error->next;
  224.         };
  225.       if( error == NULL )
  226.         {
  227.         error = ( struct elist *)malloc(sizeof(struct elist));
  228.         if( error == NULL )
  229.           {
  230.           mPrintf(" Error: No memory for vortex error list\n");
  231.           }
  232.         else
  233.           {
  234.           strcpy(error->room,  msgBuf.mbroom);
  235.           strcpy(error->nodeid, msgBuf.mborig);
  236.           error->next = head;
  237.           head        = error;
  238.           };
  239.         };
  240.       };
  241.     };
  242.   if( vortex_flag == TRUE )
  243.     {
  244.     FILE *vfd;
  245.     MESSAGE_ENTRY_TYPE *mptr = &node->msg_entry[node->next_slot];
  246.     strcpy(mptr->mborig,  msgBuf.mborig);
  247.     strcpy(mptr->mbsrcId, msgBuf.mbsrcId);
  248.     strcpy(mptr->mbdate,  msgBuf.mbdate );
  249.     strcpy(mptr->mbtime,  msgBuf.mbtime );
  250.     mptr->check_sum   = Check_Sum(msgBuf.mbtext);
  251.     node->index++;
  252.     if( node->index > MAX_VORTEX_SIZE) node->index = MAX_VORTEX_SIZE;
  253.     node->next_slot = ( node->next_slot + 1 ) % MAX_VORTEX_SIZE;
  254.     if( (vfd = fopen(vfilename, WRITE_ANY) ) == NULL )
  255.       {
  256.       mPrintf("System error with open for write of %s\n",vfilename);
  257.       }
  258.     else
  259.       {
  260.       if( fwrite(node, sizeof(ROOM_ENTRY_TYPE), 1, vfd) != 1 )
  261.         {
  262.         mPrintf("System error with write of %s\n",vfilename);
  263.         };
  264.       fclose(vfd);
  265.       };
  266.     };
  267.   free(node);
  268.   return vortex_flag;
  269.   }
  270.  
  271. /**
  272.  FinVortexing()
  273.  
  274.  This function should be called to finish a vortex checking session.
  275.  Nothing to do in this function right now.
  276. **/
  277. void FinVortexing()
  278.   {
  279.   struct elist *error;
  280.   if (!VortexHandle)  return;
  281.   if ( head == NULL ) return;
  282.   strcpy(msgBuf.mbtext, "Vortex attempted involving the following system(s): \n");
  283.   error = head;
  284.   head  = error->next;
  285.   while( error && strlen(msgBuf.mbtext) < 7000  )
  286.     {
  287.     strcat(msgBuf.mbtext, " Node Id: ");
  288.     strcat(msgBuf.mbtext, error->nodeid);
  289.     strcat(msgBuf.mbtext, " Room: ");
  290.     strcat(msgBuf.mbtext, error->room);
  291.     strcat(msgBuf.mbtext, "\n");
  292.     free(error);
  293.     error = head;
  294.     if( error ) head = error->next;
  295.     };
  296.   }
  297.  
  298. static int              Check_Sum(char *text)
  299.   {
  300.   int result = -1;
  301.   while( *text )
  302.     {
  303.     result = (result << 2) + *text++ + 3;
  304.     };
  305.   return result;
  306.   }
  307.